{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Report for aircraft-information-system-design\n",
    "* 姓名：李浩玮\n",
    "* 学号：2018300465\n",
    "\n",
    "## 内容：\n",
    "* 任务类型：路径规划\n",
    "\n",
    "* 背景介绍：目前无人机虽然实现了自动飞行，但是大部分的无人机仍不具备感知环境、动态适应环境的能力。本课题通过一步一步实现无人机的感知、路径规划、仿真，通过本项目理解无人机系统的感知与控制\n",
    "\n",
    "\n",
    "## 要求：\n",
    "\n",
    "1. 无人机从起点出发，朝向终点飞行，但是事先不知道环境地图（障碍物）的分布。\n",
    "\n",
    "2. 假设无人机上装备了激光雷达，能够探测一定范围内的障碍物信息\n",
    "\n",
    "   当前探测到的障碍物用红色显示\n",
    "\n",
    "   还未探测到的障碍物用灰色显示\n",
    "\n",
    "   已经探测到的障碍物用黑色显示\n",
    "\n",
    "3. 无人机利用A * 算法规划当前认为可行的路径，绿色的线段\n",
    "\n",
    "4. 但是随着探测范围扩大，无人机在飞行过程发现，利用之前规划的路线无法达到目标点，则需要重新规划路径\n",
    "\n",
    "5. 利用上述方法，不断探测障碍物，并不断规划路径，无人机最终到达目标点\n",
    "\n",
    "## 解决途径:\n",
    "### Step1 实现最基本的地图加载、显示\n",
    "地图文件为二进制文件，仿照老师所给的C++代码，用python实现数据的读取处理和可视化。\n",
    "地图文件的格式是一个二进制文件，文件的结构如下：\n",
    "* uint32_t (文件标识，内容是：0x15432345)\n",
    "* int32_t （map的宽度-mx，像素数）\n",
    "* int32_t （map的高度-my，像素数）\n",
    "* int8_t * mx * my (map数组，mx * my个int32_t 类型数据，具体的每个点的类型)\n",
    "* int32_t （起点的X坐标，startX）\n",
    "* int32_t （起点的Y坐标，startY）\n",
    "* int32_t （终点的X坐标，endX）\n",
    "* int32_t （终点的Y坐标，endY）\n",
    "定义好MAGIC ==np.uint32(0x15432345)，UINT_32_SIZE = 4，UINT_8_SIZE = 1 后循环读取就可以，最后作为一个二维数组，用sns.heatmap显示出地图形状，源代码如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "33 19 55 72\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "43 20 40 83\n"
     ]
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import seaborn as sns\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "MAGIC = np.uint32(0x15432345)\n",
    "UINT_32_SIZE = 4\n",
    "UINT_8_SIZE = 1\n",
    "\n",
    "def load_map(addr):\n",
    "    file = open(addr, \"rb\")\n",
    "    my_magic = int.from_bytes(file.read(UINT_32_SIZE), byteorder='little', signed=False)\n",
    "    if my_magic != MAGIC:\n",
    "        return -1\n",
    "    mx = int.from_bytes(file.read(UINT_32_SIZE), byteorder='little', signed=True)\n",
    "    my = int.from_bytes(file.read(UINT_32_SIZE), byteorder='little', signed=True)\n",
    "    _map = [[] for i in range(mx)]\n",
    "    for i in range(0, mx * my):\n",
    "        k = int(i / mx)\n",
    "        _map[k].append(int.from_bytes(file.read(UINT_8_SIZE), byteorder='little', signed=True))\n",
    "    m_start_x = int.from_bytes(file.read(UINT_32_SIZE), byteorder='little', signed=True)\n",
    "    m_start_y = int.from_bytes(file.read(UINT_32_SIZE), byteorder='little', signed=True)\n",
    "    m_end_x = int.from_bytes(file.read(UINT_32_SIZE), byteorder='little', signed=True)\n",
    "    m_end_y = int.from_bytes(file.read(UINT_32_SIZE), byteorder='little', signed=True)\n",
    "    print(m_start_x,m_start_y,m_end_x,m_end_y)\n",
    "    file.close()\n",
    "    return _map\n",
    "\n",
    "fig = plt.figure()\n",
    "sns_plot = sns.heatmap(load_map(\"test_7.map\"), cmap=\"Greys\")\n",
    "plt.show()\n",
    "fig = plt.figure()\n",
    "sns_plot = sns.heatmap(load_map(\"test_1.map\"), cmap=\"Greys\")\n",
    "plt.show()\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Step2 实现路径规划与显示\n",
    "在前面程序的基础上，实现A * 算法，在这个阶段可以假设环境地图都已知，规划全局的地图，并显示在GUI界面上。\n",
    "#### 2-1 A*算法\n",
    "A*算法是一种很常用的路径查找和图形遍历算法。它有较好的性能和准确度，是把广度优先（Breadth First）算法，Dijkstra算法，最佳优先搜索的特点集于一身的一种寻路算法。地图中每一个节点的优先级由f(n)=g(n)+h(n)求得，其中\n",
    "* f(n)是节点n的综合优先级。当我们选择下一个要遍历的节点时，我们总会选取综合优先级最高（值最小）的节点。\n",
    "* g(n) 是节点n距离起点的代价。\n",
    "* h(n)是节点n距离终点的预计代价，这也就是A*算法的启发函数。我在这里使用的是曼哈顿距离，同时只允许上下左右四个方向移动\n",
    "A*算法在运算过程中，每次从优先队列中选取f(n)值最小（优先级最高）的节点作为下一个待遍历的节点。另外，A*算法使用两个集合来表示待遍历的节点，与已经遍历过的节点，这通常称之为openset和closeset。\n",
    "完整的A*算法描述如下：\n",
    "\n",
    "* 初始化open_set和close_set；\n",
    "* 将起点加入open_set中，并设置优先级为0（优先级最高）；\n",
    "* 如果open_set不为空，则从open_set中选取优先级最高的节点n：\n",
    "    * 如果节点n为终点，则：\n",
    "        * 从终点开始逐步追踪parent节点，一直达到起点；\n",
    "        * 返回找到的结果路径，算法结束；\n",
    "    * 如果节点n不是终点，则：\n",
    "        * 将节点n从open_set中删除，并加入close_set中；\n",
    "        * 遍历节点n所有的邻近节点：\n",
    "            * 如果邻近节点m在close_set中，则：\n",
    "                * 跳过，选取下一个邻近节点\n",
    "            * 如果邻近节点m也不在open_set中，则：\n",
    "                * 设置节点m的parent为节点n\n",
    "                * 计算节点m的优先级\n",
    "                * 将节点m加入open_set中\n",
    "                \n",
    "#### 2-2 源代码以及详细注释以及结果分析\n",
    "源代码以及详细注释如下："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# -*- coding: utf-8 -*-\n",
    "\"\"\"\n",
    "Created on Mon Jan  3 16:20:14 2022\n",
    "@author: saw\n",
    "重构代码时部分借鉴了\n",
    "1.https://www.jianshu.com/p/613ef51394ec\n",
    "2.https://blog.csdn.net/qq_39687901/article/details/80753433\n",
    "中的代码例子对我的进行完善\n",
    "\"\"\"\n",
    "\n",
    "\"\"\"\"\n",
    "算法伪代码：\n",
    "1.把起点加入 open list 。\n",
    "2.重复如下过程：\n",
    "a.遍历 open list ，查找 F 值最小的节点，把它作为当前要处理的节点。\n",
    "b.把这个节点移到 close list 。\n",
    "c.对当前方格的 8 个相邻方格的每一个方格？            \n",
    "    如果它是不可抵达的或者它在 close list 中，忽略它。否则，做如下操作。\n",
    "    如果它不在 open list 中，把它加入 open list ，并且把当前方格设置为它的父亲，记录该方格的 F ， G 和 H 值。\n",
    "    如果它已经在 open list 中，检查这条路径 ( 即经由当前方格到达它那里 ) 是否更好，用 G 值作参考。更小的 G 值表示这是更好的路径。如果是这样，把它的父亲设置为当前方格，并重新计算它                                                                的 G 和 F 值。如果你的 open list 是按 F 值排序的话，改变后你可能需要重新排序。\n",
    "d.停止，当你\n",
    "    把终点加入到了 open list 中，此时路径已经找到了，或者\n",
    "    查找终点失败，并且 open list 是空的，此时没有路径。\n",
    "3.保存路径。从终点开始，每个方格沿着父节点移动直至起点，这就是你的路径。\n",
    "\"\"\"\"\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "\n",
    "#仿照老师给的C++代码读取地图文件\n",
    "MAGIC = np.uint32(0x15432345)\n",
    "UINT_32_SIZE = 4\n",
    "UINT_8_SIZE = 1\n",
    "def load_map(addr):\n",
    "    file = open(addr, \"rb\")\n",
    "    my_magic = int.from_bytes(file.read(UINT_32_SIZE), byteorder='little', signed=False)\n",
    "    if my_magic != MAGIC:\n",
    "        return -1\n",
    "    mx = int.from_bytes(file.read(UINT_32_SIZE), byteorder='little', signed=True)\n",
    "    my = int.from_bytes(file.read(UINT_32_SIZE), byteorder='little', signed=True)\n",
    "    _map = [[] for i in range(mx)]\n",
    "    for i in range(0, mx * my):\n",
    "        k = int(i / mx)\n",
    "        _map[k].append(int.from_bytes(file.read(UINT_8_SIZE), byteorder='little', signed=True))\n",
    "    m_start_x = int.from_bytes(file.read(UINT_32_SIZE), byteorder='little', signed=True)\n",
    "    m_start_y = int.from_bytes(file.read(UINT_32_SIZE), byteorder='little', signed=True)\n",
    "    m_end_x = int.from_bytes(file.read(UINT_32_SIZE), byteorder='little', signed=True)\n",
    "    m_end_y = int.from_bytes(file.read(UINT_32_SIZE), byteorder='little', signed=True)\n",
    "\n",
    "    file.close()\n",
    "    return _map\n",
    "\n",
    "#定义地图类 包括高h，宽w，数据data\n",
    "class Maplist:\n",
    "    def __init__(self,maplist):\n",
    "        self.w=np.shape(maplist)[1]\n",
    "        self.h=np.shape(maplist)[0]\n",
    "        self.data=[]\n",
    "        self.data=maplist\n",
    "    def showArray2D(self):  #绘制当前地图，暂时使用热力图heatmap看一下算法效果，最后再完善可视化\n",
    "        fig = plt.figure()\n",
    "        sns_plot = sns.heatmap(self.data, cmap=\"GnBu\")  #Greys\n",
    "        plt.show() \n",
    "    def __getitem__(self, item):\n",
    "        return self.data[item]\n",
    "   # def __getitem__(self, item):  #不手动加障碍可以注释掉\n",
    "        #return self.data[item]    \n",
    "\n",
    "#定义点类，包含点的横纵坐标\n",
    "class Point:\n",
    "    def __init__(self,x,y):\n",
    "        self.x=x;self.y=y \n",
    "    def __eq__(self, other):\n",
    "        if self.x==other.x and self.y==other.y:\n",
    "            return True\n",
    "        return False\n",
    "\n",
    "#定义A*算法主体，包括各函数，主循环\n",
    "class AStar: \n",
    "    # 定义节点 可以完美和点区分开（point和node两类）\n",
    "    class Node:  # 描述AStar算法中的节点数据\n",
    "        def __init__(self, point, endPoint, g=0):\n",
    "            self.point = point  # 当前节点的坐标\n",
    "            self.parent = None  # 上一级节点\n",
    "            self.g = g  # g()值\n",
    "            # h()值,两坐标轴之差的绝对值的和\n",
    "            self.h = (abs(endPoint.x - point.x) + abs(endPoint.y - point.y)) * 10  \n",
    " \n",
    "    def __init__(self, nowmap, startPoint, endPoint,  obstruct=1):\n",
    "        # 创建openlist和closelist\n",
    "        self.openList = []\n",
    "        self.closeList = []\n",
    "        self.nowmap = nowmap  #导入地图\n",
    "        #Astar中起点和终点\n",
    "        self.startPoint = startPoint  \n",
    "        self.endPoint = endPoint\n",
    "        #定义地图上的障碍为obstrust=1\n",
    "        self. obstruct =  obstruct\n",
    "\n",
    "    #判断节点是否在closelist中\n",
    "    def IsInCloseList(self, point):\n",
    "        for node in self.closeList:\n",
    "            if node.point == point:\n",
    "                return True\n",
    "        return False\n",
    "    \n",
    "    #判断节点是否在openlist中\n",
    "    def IsInOpenList(self, point):\n",
    "        for node in self.openList:\n",
    "            if node.point == point:\n",
    "                return node\n",
    "        return None\n",
    "\n",
    "    #找openlist中F最小的节点\n",
    "    def getMinNode(self):\n",
    "        minNode = self.openList[0]\n",
    "        for node in self.openList:\n",
    "            if node.g + node.h < minNode.g + minNode.h:\n",
    "                minNode = node\n",
    "        return minNode\n",
    "\n",
    "    #判断终点是否在openlist中，作为最终结果依据：\n",
    "    #把终点加入到了 open list 中，此时路径已经找到了，\n",
    "    #或者查找终点失败，并且 open list 是空的，此时没有路径。\n",
    "    def IsendPointInopenList(self):\n",
    "        for node in self.openList:\n",
    "            if node.point == self.endPoint:\n",
    "                return node\n",
    "        return None\n",
    "\n",
    "    #计算当前点四周的节点数据（不允许斜着走）\n",
    "    def Changenode(self, minFnode, dertaX, dertaY):\n",
    "        # 当目标点碰到边界或是障碍或是在closelist中，不做考虑直接跳过\n",
    "        if minFnode.point.x + dertaX < 0 or minFnode.point.x + dertaX > self.nowmap.w - 1 or minFnode.point.y + dertaY < 0 or minFnode.point.y + dertaY > self.nowmap.h - 1:\n",
    "            return\n",
    "        if self.nowmap[minFnode.point.x + dertaX][minFnode.point.y + dertaY] == self.obstruct:\n",
    "            return\n",
    "        nowPoint = Point(minFnode.point.x + dertaX, minFnode.point.y + dertaY)\n",
    "        if self.IsInCloseList(nowPoint):\n",
    "            return\n",
    "                # 设置g()的变量(每次移动加1)\n",
    "        derta_g = 1\n",
    "        # 如果不再openList中，就把它加入openlist，并且把当前方格设置为它的上级节点，记录该方格的 F()，G() 和H()值。\n",
    "        newNode = self.IsInOpenList(nowPoint)\n",
    "        if not newNode:\n",
    "            newNode = AStar.Node(nowPoint, self.endPoint, g=minFnode.g + derta_g)\n",
    "            newNode.parent = minFnode\n",
    "            self.openList.append(newNode)\n",
    "            return\n",
    "        \n",
    "        # 如果在openList中，判断minFnode到当前点的G是否更小\n",
    "        if minFnode.g + derta_g < newNode.g:  # 如果更小，就重新计算g值，并且改变上一级节点\n",
    "            newNode.g = minFnode.g + derta_g\n",
    "            newNode.parent = minFnode\n",
    " \n",
    "    #算法主逻辑循环\n",
    "    def start(self):\n",
    "        # 1.将起点放入openlist\n",
    "        startNode = AStar.Node(self.startPoint, self.endPoint)\n",
    "        self.openList.append(startNode)\n",
    "        # 2.主循环逻辑\n",
    "        while True:\n",
    "            # 遍历 openlist ，查找 F()值最小的节点，把它作为当前要处理的节点\n",
    "            minFnode = self.getMinNode()\n",
    "            # 把这个点加入closeList中，并且在openList中删除它\n",
    "            self.closeList.append(minFnode)\n",
    "            self.openList.remove(minFnode)\n",
    "            # 判断这个节点的上下左右节点，这里的逻辑在Changenode()函数中已经写过\n",
    "            self.Changenode(minFnode, 0, -1)\n",
    "            self.Changenode(minFnode, 0, 1)\n",
    "            self.Changenode(minFnode, -1, 0)\n",
    "            self.Changenode(minFnode, 1, 0)\n",
    "            # 判断是否终止\n",
    "            resultpoint = self.IsendPointInopenList()\n",
    "            if resultpoint != None:  # 如果终点在openlist中，则找到路径。\n",
    "                finalPoint = resultpoint\n",
    "                #创建pathlist，里面存放路径上的节点\n",
    "                pathList = []\n",
    "                #循环，倒推路径\n",
    "                while 1:\n",
    "                    if finalPoint.parent != None:\n",
    "                        pathList.append(finalPoint.point)\n",
    "                        finalPoint=finalPoint.parent\n",
    "                    #找到起点，把路线反向传出，结束。    \n",
    "                    if finalPoint.parent == None:                        \n",
    "                        return list(reversed(pathList))\n",
    "\n",
    "            # openlist是空的，此时没有路径        \n",
    "            if len(self.openList) == 0:\n",
    "                return None\n",
    "            \n",
    "if __name__ == '__main__':\n",
    "    #读地图文件\n",
    "    nowmap=Maplist(load_map(\"test_1.map\"))\n",
    "    #显示初始地图\n",
    "    nowmap.showArray2D()\n",
    "    #设置起点终点，寻路\n",
    "    aStar=AStar(nowmap,Point(20,43),Point(83,40))\n",
    "    #描绘路径\n",
    "    pathList=aStar.start()\n",
    "    for point in pathList:\n",
    "        nowmap[point.x][point.y]=0.5\n",
    "    #显示有路径的地图\n",
    "    nowmap.showArray2D()\n",
    "    \n",
    "    #读地图文件\n",
    "    nowmap=Maplist(load_map(\"test_7.map\"))\n",
    "    #显示初始地图\n",
    "    nowmap.showArray2D()\n",
    "    #设置起点终点，寻路\n",
    "    aStar=AStar(nowmap,Point(20,43),Point(83,40))\n",
    "    #描绘路径\n",
    "    pathList=aStar.start()\n",
    "    for point in pathList:\n",
    "        nowmap[point.x][point.y]=0.5\n",
    "    #显示有路径的地图\n",
    "    nowmap.showArray2D()\n",
    "\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1 可以看到上图结果：深色为障碍，较浅的为Astar找到的路径，整体路线基本是最优。这里我采用了曼哈顿距离，同时只允许上下左右四个方向移动，因为一开始是写的八个方向都可以移动，发现路线会从图形的倾斜的边缘穿过去，感觉这样和实际情况不符合，就改为了四个方向移动。\n",
    "\n",
    "2 对于h(n)函数的选取：\n",
    "* 当启发函数h(n)始终为0，则将由g(n)决定节点的优先级，此时算法就退化成了Dijkstra算法。\n",
    "* 如果h()n相较于g(n)大很多，则此时只有h(n)产生效果，这也就变成了最佳优先搜索。\n",
    "* 如果h(n)始终小于等于节点n到终点的代价，则A*算法保证一定能够找到最短路径。但是当h(n)的值越小，算法将遍历越多的节点，也就导致算法越慢。\n",
    "* 如果h(n)完全等于节点n到终点的代价，则A*算法将找到最佳路径，并且速度很快。可惜的是，并非所有场景下都能做到这一点。因为在没有达到终点之前，我们很难确切算出距离终点还有多远。\n",
    "* 如果h(n)的值比节点n到终点的代价要大，则A*算法不能保证找到最短路径，不过此时会很快。\n",
    "\n",
    "所以可以根据需求灵活选择。\n",
    "\n",
    "3 结果的可视化做的不是很好，只是用heatmap热力图画了一下开始和结果。  \n",
    "\n",
    "4 自己写完代码后看了许多前辈的代码，花了大力气重构了一下，最大的改动就是把点分两个class：point和node，这样过程就清晰了很多，python的优势也体现了出来，不需要花费心思来处理宽度很大的需要同时记录点坐标，上级点坐标的数列。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.3 - Step3 实现激光雷达的扫描"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
